package com.android.volley.http;

import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.UUID;

import com.dg.acb.utils.LogUtil;
import android.text.TextUtils;

public class MultiDataEntity implements RequestEntity {
    private final String NEW_LINE_STR = "\r\n";
    private final String CONTENT_TYPE = "Content-Type: ";
    private final String CONTENT_DISPOSITION = "Content-Disposition: ";

    private final String mBoundary = UUID.randomUUID().toString();

    private List<FormBodyPart> mFormBodyParts = new ArrayList<FormBodyPart>();

    public MultiDataEntity() {
    }

    public String getBoundary() {
        return mBoundary;
    }

    public void addPart(final String name, final String value) {
        if (LogUtil.DEBUG) {
            LogUtil.d("addPart:" + name + " => " + value);
        }
        addPart(new FormBodyPart(name, new StringBody(value)));
    }

    public void addPart(String name, String fileName, final byte[] rawData) {
        if (LogUtil.DEBUG) {
            LogUtil.d("addPart:" + name + " => [bytes Data]" + rawData.length);
        }
        addPart(new FormBodyPart(name, new BinaryBody(fileName, rawData)));
    }

    public void addPart(String name, final File file) {
        if (LogUtil.DEBUG) {
            LogUtil.d("addPart:" + name + " => [file:]" + file.length());
        }
        addPart(new FormBodyPart(name, new FileBody(file)));
    }

    public void addPart(FormBodyPart fPart) {
        mFormBodyParts.add(fPart);
    }

    public void writeTo(OutputStream out) throws IOException {
        Collections.sort(mFormBodyParts,
                new FormBodyPart.FormBodyComparator());
        for (FormBodyPart formBodyPart : mFormBodyParts) {
            writeBoundary(out);
            ContentBody contentBody = formBodyPart.getBody();
            String type = contentBody.getContentType();
            String fileName = contentBody.getFileName();
            //String contentTransferEncoding = contentBody.getContentTransferEncoding();
            String paramName = formBodyPart.getName();
            out.write(getContentDispositionBytes(paramName, fileName));
            if (contentBody instanceof BinaryBody) {
                out.write((NEW_LINE_STR + CONTENT_TYPE + type).getBytes());
            }
            out.write((NEW_LINE_STR + NEW_LINE_STR).getBytes());
            contentBody.writwTo(out);
            out.write(NEW_LINE_STR.getBytes());
        }
        writeEndBoundary(out);
    }

    private void writeBoundary(OutputStream out) throws IOException {
        out.write(("--" + mBoundary + "\r\n").getBytes());
    }

    /** 添加结尾数据*/
    private void writeEndBoundary(OutputStream out) throws IOException {
        out.write(("--" + mBoundary + "--" + "\r\n\r\n").getBytes());
    }

    private byte[] getContentDispositionBytes(String paramName, String fileName) {
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append(CONTENT_DISPOSITION + "form-data; name=\"" + paramName + "\"");
        if (!TextUtils.isEmpty(fileName)) {
            stringBuilder.append("; filename=\"" + fileName + "\"");
        }
        if (LogUtil.DEBUG) {
            LogUtil.d(paramName + " => " + stringBuilder.toString());
        }
        return stringBuilder.toString().getBytes();
    }

    @Override
    public String getContentType() {
        return "multipart/form-data; boundary=" + getBoundary();
    }

    @Override
    public String getContentEncoding() {
        return DEFAULT_PARAMS_ENCODING;
    }
}